#include "BudgetPlanner.h"
#include <iostream>
#include <string>

using namespace std;

BudgetPlanner::BudgetPlanner(){
}

BudgetPlanner::BudgetPlanner(Budget foodIn, Budget transportationIn, Budget accomodationIn, Budget academicsIn, Budget recreationIn, Budget debtsIn, Budget othersIn){
}

//non exhaustive - must refine
void BudgetPlanner:: errorhandler(){
		
	    cin.clear();
		cin.ignore(100, '\n');
		cout << "Invalid input. Please, try again" << endl;
}

void BudgetPlanner::settimeframe(int tf){  
	timeframe = tf;
}

void BudgetPlanner::setdetails(int j)
{
	int i, priority, k;
	bool parr[7] = {0};
	double budget, tempbudget;
	string categories[7] = {"Accomodation", "Academics", "Debts", "Food", "Recreation", "Transportation", "Others"};

	if (j == 0)
	{
		cout << "Enter Total Budget: ";
		cin >> totalbudget;
		while(cin.fail())
		{
			errorhandler();
			cin >> totalbudget;
		}		
	}
	tempbudget = totalbudget;

	cout << "Enter the budget for each category followed by its priority(1-7) " << endl;

	for (i = 0; i < 7; i++)
	{
		if (i != 2)
			cout << categories[i] << " Budget: ";
		else
			cout << categories[i] << " : " ;
		
		cin >> budget;
		if(cin.fail())
		{
			errorhandler();
			i--;
			continue;
		}
		tempbudget-=budget;
		if (tempbudget < 0)
		{
			cout << "You have exceeded the total budget. Please start over." << endl;
			cout << "------------------------------------------------------------------"<< endl;
			i = -1;
			tempbudget = totalbudget;
			for (k = 0; k < 7; k++){
				parr[k] = 0;}
				
			continue;
		}
		else
			cat[i].setInitialBudget(budget);

		//after budget settled, user enters priority
		cout << "Priority: ";
		cin >> priority;
		//handling invalid input
		while ((cin.fail() || parr[priority - 1]) && priority != 0) 
		{
			//input invalid
			if (cin.fail())
				errorhandler();
			else if (parr[priority - 1]) 
				cout << "Priority entered is already in use. Please enter a different value or 0 to start over " << endl;
			
			cout << categories[i] << " Budget: " << cat[i].getInitial() << endl << "Priority: ";
			cin >> priority;
		}			
		if (priority == 0)
		{		
			cout << "------------------------------------------------------------------"<< endl;
			i = -1;
			tempbudget = totalbudget;
			for (k = 0; k < 7; k++){
				parr[k] = 0;}

			continue;
		}
		parr[priority -1] = true;
		cat[i].setp(priority);
	}

}
void BudgetPlanner::add(int categ, double change, double numdays)
{
	totalbudget += change;
	int command;
	string categories[7] = {"Accomodation", "Academics", "Debts", "Food", "Recreation", "Transportation", "Others"};
	double difference = 0;
	//assume categ goes from 0-6, 0 for food , 6 for others
	double proportion =  1 - numdays/timeframe;
	//cout << "proportion is: " << proportion << endl;
	difference = (cat[categ]).add(change, proportion);
	//cout << "difference is : " << difference << endl;
	view();
	
	//cout << "difference is : " << difference << endl;
	if (difference > 0)
	{
		cout << "You have exceeded the budget for " << categories[categ] << " by " << difference << endl;
		cout << "Enter 0 to change budget values or 1 to let budgetplanner decide" << endl;
		cin >> command;
		while (cin.fail())
		{	
			errorhandler();
			cin >> command;
		}
		if (command == 1)
		{
			realloc(difference, categ, (cat[categ]).getp(), proportion);
			view();
			cout << "Press 0 to change budget values or 1 to keep current settings" << endl;
			cin >> command;
			while (cin.fail())
			{	
				errorhandler();
				cin >> command;
			}
		}
		if (command == 0)
		{
			//resets values - note that each time new expense added, under budget category will alarm
			timeframe -=numdays;
			cout << "Total remaining budget: " << totalbudget << endl;
			setdetails(1);
		}
	}

}

void BudgetPlanner::view()
{
	string categories[7] = {"Accomodation", "Academics", "Debts", "Food", "Recreation", "Transportation", "Others"};
	
	for (int i = 0; i < 7; i++)
	{
		cout << categories[i] << ":" << endl;
		cout << "Initial Budget: " << cat[i].getInitial() <<  " Remaining Budget: " << cat[i].getLeftover() << endl;
	}
	cout << "--------------------------------------------------------------------------" << endl;

}

void BudgetPlanner::realloc(double difference, int categ, int p, double proportion)
{
	int i, p1;
	double excess, x = 0;
	double greater = 7 - p;

	//clearing all excesses
	for ( i = 0; i < 7; i++)
	{
		if (i == categ)
			continue;
		//cout << "inside loop and difference is:" << difference << endl;

		excess = cat[i].getLeftover() - ((cat[i].getInitial()) * proportion);
		//cout << "excess is " << excess << endl;
		//cout << "excess is: " << excess << endl;
		
		if (difference > excess && excess >= 0)
		{
			//cout << " in if statement" << endl;
			difference -= excess;
			cat[i].simpleadd(excess);
		}
		else if (difference < excess && excess >=0)
		{
			//cout << " in else statement" << endl;
			cat[i].simpleadd(difference);
			cat[categ].simpleadd(-difference);
			difference = 0;
			break;
		}
	}
		
	//difference  still not equal to 0
	//for every priority lower, 10 percent more will be taken from that category
	//first term + last term * ( n /2)
	if (difference > 0)
	{
		//cout << "diffference after absorbing all excesses is : " << difference << endl;
		if (categ != 6)
			cat[categ].simpleadd(-difference);
		//cout << "greater is: " <<  greater << endl;
		x = (2 + (greater - 1)*0.1) * (greater/2);
		//cout << "x is : " << x << endl;
		for (i = 0; i < 7; i++)
		{
			p1 = cat[i].getp();
			if (p1 > p)
			{
				//cout << "inside if statement" << endl;
				cat[i].simpleadd(((difference) * ((1 + (0.1 *(p1 - p - 1)))/x)));
			}
		}
	}
}













